minifill.js - the essential polyfill
Ever wondered how to fix old browsers, improve scripting execution performance, simplify scripting and improve overall code quality all without using jQuery? The answer is polyfills.
The polyfills come from various sources to which I give full credits:
- Financial Times polyfill service
- Remy Sharp (the one who came with the name of
polyfill
) - Mozilla Developer Network
When you use the above service, there is a certain amount of delay involved when executing the polyfill queries, as well as some unexplained in page script execution lags, a case where it's best to just host your own polyfills, and here comes minifill handy.
TIP: My other libraries such as bootstrap.native and KUTE.js work best with minifill.
A minimal polyfill with most essential stuff:
-
this.Document - IE8 doesn't know who is this.Document
, it's this.HTMLDocument
-
this.Window - older Safari doesn't know who is this.Window
, it's this
-
window.HTMLElement - IE8 doesn't know who is window.Element
, it's window.HTMLElement
-
window.Node - IE8 doesn't know who is window.Node
, it's window.Element
-
Object.defineProperty - important for the below classList
-
Object.keys - returns an array populated with the object's keys
-
Array.from - creates a new, shallow-copied Array
instance from an array-like or iterable object, usually NodeList
, HTMLCollection
-
Array.prototype.every - tests whether all elements in the array pass the test implemented by the provided function
-
Array.prototype.find - returns the value of the first element in the provided array that satisfies the provided testing function
-
Array.prototype.forEach - executes a provided function once for each array element.
-
Array.prototype.includes - determines whether an array includes a certain value among its entries
-
Array.prototype.map - creates a new array populated with the results of calling a provided function on every element in the calling array
-
Array.prototype.some - tests whether at least one element in the array passes the test implemented by the provided function
-
Multi.prototype.indexOf - checks inside strings and arrays for particular values
-
Multi.addEventListener - uses the deprecated attachEvent
API to help legacy browsers
-
Multi.getElementsByClassName - a querySelectorAll
based polyfill for document
/Element
-
Multi.Event - the complete polyfill, implements createEvent
or createEventObject
to make HTML4 browsers as well as IE8-IE11 work properly with today's standard Event
-
Multi.CustomEvent - the complete polyfill, makes use of the above new Event()
for stuff like unsupported events types or user defined events like my.custom.event
, this also works with IE8-IE11
-
Multi.dispatchEvent - uses the deprecated fireEvent
API on legacy browsers
-
Element.prototype.matches - the complete matches
polyfill
-
Element.prototype.classList - class manipulation mostly for IE8 and other HTML4 browsers, inspired by Remy's classList
-
Element.prototype.closest - uses the above matches
to find the closest parent element that matches the selector
-
Date.now - required by the below requestAnimationFrame
and other stuff, uses the new Date().getTime()
synthax to return the current time
-
String.prototype.includes - a quick fill by MDN
-
String.prototype.trim - yeah trim
eventually
-
Node.prototype.contains - checks for parental relation between elements
-
NodeList.prototype.forEach - simple forEach
polyfill, executes a provided function once for each element in a Nodelist
.
-
window.getComputedStyle - the complete getComputedStyle
polyfill, returns the true dimensions, spacing, or other browser supported properties
-
window.performance.now - required for KUTE.js and other stuff, when accuracy is required for the current time
-
window.requestAnimationFrame - also required for KUTE.js
What is minifill.js for
- HTML4 browsers that don't support/recognize these methods/objects
- all IE browsers don't have any/enough support for the today's standard
Event
- busting the myth of
write less, do more
How to use minifill.js
- Download or copy link from jsdelivr or cdnjs
- Add one of the following to your head tag
<script type="text/javascript" src="../assets/js/minifill.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/thednp/minifill@0.0.4/dist/minifill.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/minifill/0.0.4/minifill.min.js"></script>
Custom builds
You can create your own builds specific to your application bundles, but make sure to keep the same order as for the minifill.js
.
- create a new file
/path-to/your-file.js
- copy contents of the
minifill.js
- edit out the polyfills you don't need
- run
npm run custom INPUTFILE:path-to/your-file.js,OUTPUTFILE:path-to/your-build.js,FORMAT:esm,MIN:false
** INPUTFILE
- allows you to specify the source file path
** OUTPUTFILE
- allows you to specify the output file path
** MIN
- when true, it will compress the output
** FORMAT
- umd|cjs|esm and any format you specify or configure your rollup for
Examples
Class Manipulation
var docHasClass = myElement.classList.contains('someClass');
myElement.classList.add('someClass');
myElement.classList.remove('someClass');
myElement.classList.toggle('someClass');
String / Array checks
string.indexOf('looking for this');
array.indexOf(myElement);
Get current computed style for an element
var elStyle = window.getComputedStyle(myElement);
var width = elStyle.width;
Get the exact current time
var timeNow = window.performance.now();
Create Native Events
Instead of writing
if ( 'createEventObject' in document ) {
myChangeEvent = document.createEventObject();
myChangeEvent.type = type;
myChangeEvent.bubbles = bubbles;
myChangeEvent.cancelable = cancelable;
} else {
myChangeEvent = document.createEvent('Event');
myChangeEvent.initEvent(type, bubbles, cancelable);
}
you can simply write
var myChangeEvent = new Event('change');
to do it all for you.
Create Custom Events
var myCustomEvent = new CustomEvent('my.custom.event.name');
Triggering/Dispatching Events
myElement.dispatchEvent(myChangeEvent);
myElement.dispatchEvent(myCustomEvent);
Adding Event Handlers
window.addEventListener('scroll',handler,false);
myButton.addEventListener('click',handler,false);
Removing Event Handlers
window.removeEventListener('scroll',handler,false);
myButton.removeEventListener('click',handler,false);
NOTE: if the removeEventListener
call is not in the same context with addEventListener
, it will produce no effect. If you would like to autoremove a handler, you would need to write your code like this:
window.addEventListener('scroll', function handlerWrapper(e){
handler(e);
window.removeEventListener('scroll', handlerWrapper, false);
},false);
License
minifill.js is licensed under MIT License.